package com.project.web.admin.controller.common;

import com.project.web.admin.utils.freemarker.directive.FlashMessageDirective;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.yun.common.utils.appInterface.Message;

import javax.validation.ConstraintViolation;
import java.io.Serializable;
import java.util.Set;

/**
 * controller 抽象类
 */
@Component
public abstract class AbstractController implements Serializable {

    protected Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 错误消息
     */
    protected static final Message ERROR_MESSAGE = Message.error("操作失败");

    /**
     * 错误消息
     */
    protected static final Message ERROR_GETDATA_MESSAGE = Message.error("获取数据失败");

    /**
     * 成功消息
     */
    protected static final Message SUCCESS_MESSAGE = Message.success("操作成功");

    /**
     * 操作对象不存在
     */
    protected static final Message NOTEXIST_MESSAGE = Message.error("操作的对象不存在或已被删除");

    /**
     * "验证结果"参数名称
     */
    protected static final String CONSTRAINT_VIOLATIONS_ATTRIBUTE_NAME = "constraintViolations";

    @Autowired
    protected LocalValidatorFactoryBean LocalValidatorFactoryBean;


    /**
     * 数据验证
     *
     * @param target 验证对象
     * @param groups 验证组
     * @return 验证结果
     */
    protected boolean isValid(Object target, Class<?>... groups) {
        Set<ConstraintViolation<Object>> constraintViolations = LocalValidatorFactoryBean.validate(target, groups);
        if (constraintViolations.isEmpty()) {
            return true;
        } else {
            RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
            requestAttributes.setAttribute(CONSTRAINT_VIOLATIONS_ATTRIBUTE_NAME, constraintViolations, RequestAttributes.SCOPE_REQUEST);
            return false;
        }
    }

    /**
     * 数据验证
     *
     * @param type     类型
     * @param property 属性
     * @param value    值
     * @param groups   验证组
     * @return 验证结果
     */
    protected boolean isValid(Class<?> type, String property, Object value, Class<?>... groups) {
        Set<?> constraintViolations = LocalValidatorFactoryBean.validateValue(type, property, value, groups);
        if (constraintViolations.isEmpty()) {
            return true;
        } else {
            RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
            requestAttributes.setAttribute(CONSTRAINT_VIOLATIONS_ATTRIBUTE_NAME, constraintViolations, RequestAttributes.SCOPE_REQUEST);
            return false;
        }
    }

    /**
     * 添加瞬时消息--用于redirect
     *
     * @param redirectAttributes RedirectAttributes
     * @param message            消息
     */
    protected void addFlashMessage(RedirectAttributes redirectAttributes, Message message) {
        if (redirectAttributes != null && message != null) {
            redirectAttributes.addFlashAttribute(FlashMessageDirective.FLASH_MESSAGE_ATTRIBUTE_NAME, message);
        }
    }

    /**
     * 添加信息到model--用于foward
     *
     * @param model
     * @param message
     */
    protected void addFlashMessage(Model model, Message message) {
        if (model != null && message != null) {
            model.addAttribute(FlashMessageDirective.FLASH_MESSAGE_ATTRIBUTE_NAME, message);
        }
    }

    /**
     * 添加弹出layer层的提示信息
     */
    protected void addLayerFlashMessage(Model model) {
        addLayerFlashMessage(model, true, SUCCESS_MESSAGE, 1);
    }

    /**
     * 添加弹出layer层的提示信息，并关闭指定layer层数
     */
    protected void addLayerFlashMessage(Model model, Integer layerNum) {
        addLayerFlashMessage(model, true, SUCCESS_MESSAGE, layerNum);
    }

    /**
     * 添加弹出layer层的提示信息
     *
     * @param isReloadParent 是否刷新父窗口
     * @param message        提示信息
     */
    protected void addLayerFlashMessage(Model model, boolean isReloadParent, Message message) {
        addLayerFlashMessage(model, isReloadParent, message, 1);
    }

    /**
     * 添加弹出layer层的提示信息
     *
     * @param isReloadParent 是否刷新父窗口
     * @param message        提示信息
     * @param layerNum       layer层数
     */
    protected void addLayerFlashMessage(Model model, boolean isReloadParent, Message message, Integer layerNum) {
        model.addAttribute("isReloadParent", isReloadParent);
        model.addAttribute("tipMess", message);
        model.addAttribute("layerNum", layerNum);
    }

    /**
     * 添加弹出layer层的提示信息
     *
     * @param parentUrl 指定父窗口的url
     * @param message   提示信息
     */
    protected void addLayerFlashMessage(Model model, String parentUrl, Message message) {
        model.addAttribute("parentUrl", parentUrl);
        model.addAttribute("tipMess", message);
    }

}
